package cn.gglol.code.generator.utils;

import cn.gglol.code.generator.Config;
import cn.gglol.code.generator.domain.JvvTable;
import cn.gglol.code.generator.domain.JvvTableColumn;
import cn.gglol.code.generator.mapper.JvvTableColumnMapper;
import cn.gglol.code.generator.mapper.JvvTableMapper;
import org.apache.ibatis.datasource.pooled.PooledDataSourceFactory;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;

import javax.sql.DataSource;
import java.util.List;
import java.util.Properties;

/**
 * @author <a href='Jvvtao:jwtao520@qq.com'>Jvvtao<a/>
 * @since
 */
public class DatabaseHelpers {
    private final String URL = "jdbc:mysql://{ip}:{port}/{db}?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8";

    private DataSource dataSource;

    private SqlSessionFactory sqlSessionFactory;

    private DatabaseHelpers() {
    }

    /** 生成实例 */
    public static DatabaseHelpers generate() {
        DatabaseHelpers databaseHelpers = new DatabaseHelpers();
        databaseHelpers.buildDataSource();
        databaseHelpers.buildSqlSessionFactory();
        return databaseHelpers;
    }

    /** 获取表信息 */
    public JvvTable getTable(String tableName) {
        try (SqlSession session = sqlSessionFactory.openSession()) {
            JvvTableMapper mapper = session.getMapper(JvvTableMapper.class);
            return mapper.selectTableByName(tableName);
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    /** 获取表字段信息 */
    public List<JvvTableColumn> getTableColumn(String tableName) {
        try (SqlSession session = sqlSessionFactory.openSession()) {
            JvvTableColumnMapper mapper = session.getMapper(JvvTableColumnMapper.class);
            return mapper.selectDbTableColumnsByName(tableName);
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    /** 构建 SqlSessionFactory */
    private void buildSqlSessionFactory() {
        TransactionFactory transactionFactory = new JdbcTransactionFactory();
        Environment environment = new Environment("development" , transactionFactory, dataSource);
        Configuration configuration = new Configuration(environment);
//        configuration.setLogImpl(StdOutImpl.class); // 日志输出类
        configuration.addMapper(JvvTableMapper.class); // 添加表文件查询映射类
        configuration.addMapper(JvvTableColumnMapper.class); // 添加表字段查询映射类
        this.sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
    }


    /** 构建 DataSource */
    private void buildDataSource() {
        Properties properties = new Properties();
        properties.setProperty("driver" , "com.mysql.cj.jdbc.Driver");
        properties.setProperty("url" , buildUrl());
        properties.setProperty("username" , Config.getUsername());
        properties.setProperty("password" , Config.getPassword());

        PooledDataSourceFactory pooledDataSourceFactory = new PooledDataSourceFactory();
        pooledDataSourceFactory.setProperties(properties);
        this.dataSource = pooledDataSourceFactory.getDataSource();
    }

    /** 构建数据库连接 url */
    private String buildUrl() {
        return URL.replace("{ip}" , Config.getIp())
                .replace("{port}" , String.valueOf(Config.getPort()))
                .replace("{db}" , Config.getDbName());
    }
}
